package com.x.uikit.page;

import android.content.Context;

import androidx.annotation.NonNull;

import java.util.LinkedList;

public class XPageStack extends XPageLayer {
    private LinkedList<XPage> mStack = new LinkedList<>();
    private XPage mRootPage;

    public XPageStack(@NonNull Context context, @NonNull XPage page) {
        super(context);
        mRootPage = page;
        push(page, null);
    }


    public void push(XPage page, IPageAnimator animator) {
        if (page == null) {
            return;
        }
        final XPage backPage = mStack.peek();
        mStack.push(page);
        final XPage frontPage = page;
        //回调前台page生命周期
        frontPage.getLifecycle().update(XLifecycle.State.CREATE);
        getThis().addView(page);
        if (animator != null) {
            animator.start(IPageAnimator.Type.PUSH, frontPage, backPage, new IPageAnimator.OnAnimateListener() {
                @Override
                public void onStart() {
                    frontPage.getLifecycle().update(XLifecycle.State.START);
                }

                @Override
                public void onEnd() {
                    if (backPage != null) {
                        backPage.getLifecycle().update(XLifecycle.State.PAUSE);
                    }
                    frontPage.getLifecycle().update(XLifecycle.State.RESUME);
                    if (backPage != null) {
                        backPage.getLifecycle().update(XLifecycle.State.STOP);
                    }
                }
            });
        } else {
            frontPage.getLifecycle().update(XLifecycle.State.START);
            if (backPage != null) {
                backPage.getLifecycle().update(XLifecycle.State.PAUSE);
            }
            frontPage.getLifecycle().update(XLifecycle.State.RESUME);
            if (backPage != null) {
                backPage.getLifecycle().update(XLifecycle.State.STOP);
            }
        }

    }

    public boolean canPop() {
        return mStack.size() > 1;
    }

    public void pop(IPageAnimator animator) {
        if (!canPop()) {
            return;
        }
        final XPage frontPage = mStack.pop();
        final XPage backPage = mStack.peek();
        popInner(frontPage, backPage, animator);
    }

    private void popInner(final XPage frontPage, final XPage backPage, IPageAnimator animator) {
        if (animator != null) {
            animator.start(IPageAnimator.Type.POP, frontPage, backPage, new IPageAnimator.OnAnimateListener() {
                @Override
                public void onStart() {
                    if (backPage != null) {
                        backPage.getLifecycle().update(XLifecycle.State.START);
                    }
                }

                @Override
                public void onEnd() {
                    frontPage.getLifecycle().update(XLifecycle.State.PAUSE);
                    if (backPage != null) {
                        backPage.getLifecycle().update(XLifecycle.State.RESUME);
                    }
                    frontPage.getLifecycle().update(XLifecycle.State.STOP);
                    getThis().removeView(frontPage);
                    frontPage.getLifecycle().update(XLifecycle.State.DESTROY);
                }
            });

        } else {
            frontPage.getLifecycle().update(XLifecycle.State.PAUSE);
            if (backPage != null) {
                backPage.getLifecycle().update(XLifecycle.State.RESUME);
            }
            frontPage.getLifecycle().update(XLifecycle.State.STOP);
            getThis().removeView(frontPage);
            frontPage.getLifecycle().update(XLifecycle.State.DESTROY);
        }
    }

    public void popToRoot(IPageAnimator animator) {
        popTo(mRootPage, animator);

    }

    public void popTo(XPage page, IPageAnimator animator) {
        if (page == null || !canPop() || !mStack.contains(page)) {
            return;
        }
        int count = mStack.size();
        if (count < 2) {
            return;
        }
        final XPage frontPage = mStack.peek();
        int target = mStack.indexOf(page);
        for (int i = count - 2; i > target; i--) {
            remove(i);
        }
        popInner(frontPage, page, animator);
    }

    @Override
    public boolean onBackPressed() {
        XPage page = peek();
        if (page != null && page.onBackPressed()) {
            return true;
        }
        return super.onBackPressed();
    }

    private XPageStack getThis() {
        return this;
    }

    public XPage peek() {
        return mStack.peek();
    }

    public XPage peekSecond() {
        if (mStack.size() > 1) {
            return mStack.get(mStack.size() - 2);
        }
        return null;
    }

    private void remove(int pageIndex) {
        XPage targetPage = mStack.remove(pageIndex);
        getThis().removeView(targetPage);
        targetPage.getLifecycle().update(XLifecycle.State.DESTROY);
    }

    public void remove(XPage page) {
        if (page == null) {
            return;
        }
        int target = mStack.indexOf(page);
        if (target >= 0) {
            remove(target);
        }
    }

    public void destroy() {
        for (XPage page : mStack) {
            if (page != null) {
                getThis().removeView(page);
                page.getLifecycle().update(XLifecycle.State.DESTROY);
            }
        }
    }
}
